package org.abratuhi.kvngroupware.network;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

import org.abratuhi.kvngroupware.server.KVNGroupwareServer;


public class S_Client implements Runnable{
	/**/
	public Server server;
	public Socket clientSocket;
	public boolean runOK = false;
	public Thread thread;
	
	
	/**/
	KVNGroupwareServer kvnserver;
	
	/**/
	public S_Client(Server serv, Socket s){
		this.server = serv;
		this.clientSocket = s;
		this.kvnserver = server.kvnserver;
		setRunOK(true);
	}
	
	/**/
	public void sendMessage(Message msg){
		if(clientSocket!=null && !clientSocket.isClosed()){
		try {
			new DataOutputStream(clientSocket.getOutputStream()).writeUTF(msg.toString());
		} catch (IOException e) {
			e.printStackTrace();
			stop();
			server.getClients().remove(this);
		}
		}
	}
	public Message receiveMessage(){
		String strMsg = null;
		if(clientSocket != null && !clientSocket.isClosed()){
		try {
			strMsg = new DataInputStream(clientSocket.getInputStream()).readUTF();
			if(strMsg != null && strMsg != ""){
				return Message.fromMessage(strMsg);
			}
			else{
				return null;
			}
		} catch (IOException e) {
			e.printStackTrace();
			stop();
			server.getClients().remove(this);
		}
		}
		return null;
	}
	
	/**/
	public void run(){
		while(getRunOK()){
			try {
				Message msg = receiveMessage();

				/* place message into pool for further proceeding */
				//server.addIncomingMessage(msg);
				if(msg!=null) kvnserver.proceedMessage(msg);
				
				Thread.sleep(100);
				
			} catch (InterruptedException e) {
				System.out.println("S_Client:\tinterrupted.");
				//setRunOK(false);
				break;
			}
		}
		System.out.println("S_Client:\tstopped.");
	}
	
	public void start(){
		this.setRunOK(true);
		this.thread = new Thread(this);
		this.thread.start();
	}
	
	public void stop(){
		setRunOK(false);
		thread.interrupt();
	}
	
	/**/
	
	public synchronized boolean getRunOK(){
		return this.runOK;
	}
	
	public synchronized void setRunOK(boolean run){
		this.runOK = run;
	}
	
	public synchronized void switchRunOK(){
		this.runOK = (this.runOK == true)? false:true;
	}

}

